﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Data;

namespace OpenSource.Controls
{

    [DefaultProperty("Text")]
    [ToolboxData("<{0}:InputForm runat=server></{0}:InputForm>")]
    public class InputForm : CompositeDataBoundControl, IPostBackContainer
        //, IPostBackEventHandler, ICallbackContainer,ICallbackEventHandler
    {
        #region variables


        private static readonly object EventCellCreating = new object();
        private static readonly object EventCellCreated = new object();
        private static readonly object EventCellCommand = new object();

        private static readonly object EventRowCreated = new object();
        private static readonly object EventRowChanged = new object();

        #endregion

        private TableRowStyle _rowStyle;
        private TableRowStyle _alternateRowStyle;

        private InputFormRowCollection _rowCollection;

        #region constructors

        static InputForm()
        {
        }

        public InputForm()
        {
        }

        #endregion

        #region properties

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public string Text
        {
            get
            {
                String s = (String) ViewState["Text"];
                return ((s == null) ? "[OpenSource.Controls." + this.ID + "]" : s);
            }

            set { ViewState["Text"] = value; }
        }


        [PersistenceMode(PersistenceMode.InnerProperty)]
        [Description("View_RowStyle")]
        [NotifyParentProperty(true)]
        [Category("Styles")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public TableRowStyle TableRowStyle
        {
            get
            {
                if (this._rowStyle == null)
                {
                    this._rowStyle = new TableRowStyle();
                    if (this.IsTrackingViewState)
                        this._rowStyle.TrackViewState();
                }
                return this._rowStyle;
            }
        }



        [PersistenceMode(PersistenceMode.InnerProperty)]
        [Description("View_RowStyle")]
        [NotifyParentProperty(true)]
        [Category("Styles")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public TableRowStyle AlternateTableRowStyle
        {
            get
            {
                if (this._alternateRowStyle == null)
                {
                    this._alternateRowStyle = new TableRowStyle();
                    if (this.IsTrackingViewState)
                        this._alternateRowStyle.TrackViewState();
                }
                return this._alternateRowStyle;
            }
        }

        //[Description("InputForm_Rows")]
        //[Browsable(false)]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        [MergableProperty(false)]
        [Category("Default")]
        [DefaultValue(null)]
        //[Editor(
        //    "System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        //    , typeof(UITypeEditor))]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [Description("DataControls_Columns")]
        public InputFormRowCollection Rows
        {
            get
            {
                if (this._rowCollection == null)
                {
                    this._rowCollection = new InputFormRowCollection();
                    //this._rowCollection.
                    if (this.IsTrackingViewState)
                        this._rowCollection.TrackViewState();
                }
                return this._rowCollection;
            }
        }


        
        [Description("DataControls_AutoGenerateColumns")]
        [Category("Behavior")]
        [DefaultValue(true)]
        public virtual bool AutoGenerateRows
        {
            get
            {
                object obj = this.ViewState["AutoGenerateColumns"];
                if (obj != null)
                    return (bool) obj;
                else
                    return true;
            }
            set
            {
                bool autoGenerateColumns = this.AutoGenerateRows;
                if (value == autoGenerateColumns)
                    return;
                this.ViewState["AutoGenerateColumns"] = (object) value; // false; //;
                if (!this.Initialized)
                    return;
                this.RequiresDataBinding = true;
            }
        }





        #endregion


        #region event and delegate

        [Category("Action")]
        [Description("DataControls_OnRowCreated")]
        public event InputFormRowEventHandler RowCreated
        {
            add { this.Events.AddHandler(InputForm.EventRowCreated, (Delegate) value); }
            remove { this.Events.AddHandler(InputForm.EventRowCreated, (Delegate) value); }
        }

        [Category("Action"), Description("Raised when the SelectedIndex property has changed.")]
        public event InputFormRowChangedEventHandler RowChanged
        {
            add { Events.AddHandler(InputForm.EventRowChanged, value); }
            remove { Events.RemoveHandler(InputForm.EventRowChanged, value); }
        }


        [Category("Action")]
        [Description("DataControls_OnCellCreating")]
        public event InputFormCellEventHandler CellCreating
        {
            add { this.Events.AddHandler(InputForm.EventCellCreating, (Delegate) value); }
            remove { this.Events.AddHandler(InputForm.EventCellCreating, (Delegate) value); }
        }

        [Category("Action")]
        [Description("DataControls_OnCellCreated")]
        public event InputFormCellEventHandler CellCreated
        {
            add { this.Events.AddHandler(InputForm.EventCellCreated, (Delegate) value); }
            remove { this.Events.AddHandler(InputForm.EventCellCreated, (Delegate) value); }
        }


        [Category("Action")]
        [Description("DataControls_OnCellCreated")]
        public event InputFormCellCommandEventHandler CellCommand
        {
            add { this.Events.AddHandler(InputForm.EventCellCommand, (Delegate) value); }
            remove { this.Events.AddHandler(InputForm.EventCellCommand, (Delegate) value); }
        }

        #endregion


        #region event fire method      

        protected virtual void OnCellCreating(InputFormCellEventArgs e)
        {
            InputFormCellEventHandler handler = (InputFormCellEventHandler) this.Events[InputForm.EventCellCreating];
            if (handler != null)
                handler((object) this, e);
        }

        protected virtual void OnCellCreated(InputFormCellEventArgs e)
        {
            InputFormCellEventHandler handler = (InputFormCellEventHandler) this.Events[InputForm.EventCellCreated];
            if (handler != null)
                handler((object) this, e);
        }

        protected virtual void OnCellCommand(InputFormCellCommandEventArgs e)
        {
            InputFormCellCommandEventHandler handler =
                (InputFormCellCommandEventHandler) this.Events[InputForm.EventCellCommand];
            if (handler != null)
                handler((object) this, e);
        }

        protected virtual void OnRowCreated(InputFormRowEventArgs e)
        {
            InputFormRowEventHandler handler = (InputFormRowEventHandler) this.Events[InputForm.EventRowCreated];
            if (handler != null)
                handler((object) this, e);
        }

        protected virtual void OnRowChanged(InputFormRowChangedEventArgs e)
        {
            InputFormRowChangedEventHandler handler = (InputFormRowChangedEventHandler) Events[EventRowChanged];
            if (handler != null)
                handler(this, e);
        }

        #endregion


        #region override methods

        #region viewstate and control state method

        protected override object SaveViewState()
        {
            object obj1 = base.SaveViewState();
            
            object obj2 = this._rowStyle != null ? this._rowStyle.SaveViewState() : (object) null;
            object obj3 = this._alternateRowStyle != null ? this._alternateRowStyle.SaveViewState() : (object) null;

            object obj4 = this._rowCollection != null ? this._rowCollection.SaveViewState() : (object) null;

            object[] viewSateObjects = new object[4] {obj1, obj2, obj3,obj4};
            return viewSateObjects;
        }

        protected override void LoadViewState(object savedState)
        {
            if (savedState != null)
            {
                object[] objArray1 = (object[]) savedState;
                base.LoadViewState(objArray1[0]);
                if (objArray1[1] != null)
                    this._rowStyle.LoadViewState(objArray1[1]);
                if (objArray1[2] != null)
                    this._alternateRowStyle.LoadViewState(objArray1[2]);
            }
        }

        protected override void TrackViewState()
        {
            base.TrackViewState();
            if (this._rowStyle != null)
                this._rowStyle.TrackViewState();
            if (this._alternateRowStyle != null)
                this._alternateRowStyle.TrackViewState();
        }

        protected override object SaveControlState()
        {
            return base.SaveControlState();
        }

        protected override void LoadControlState(object savedState)
        {
            base.LoadControlState(savedState);
        }

        #endregion




        public override void DataBind()
        {
            base.DataBind();
        }

        protected override void Render(HtmlTextWriter writer)
        {
            this.Render(writer, false);
        }

        private void Render(HtmlTextWriter writer, bool renderPanel)
        {
            if (this.Page != null)
                this.Page.VerifyRenderingInServerForm((Control) this);
            this.PrepareControlHierarchy();
            if (renderPanel)
            {
                string clientId = this.ClientID;
                if (this.DetermineRenderClientScript())
                {
                    if (clientId == null)
                        throw new HttpException(CustomString.GetString("GridView_MustBeParented"));
                    StringBuilder stringBuilder = new StringBuilder("__gv", clientId.Length + 9);
                    stringBuilder.Append(clientId);
                    stringBuilder.Append("__div");
                    writer.AddAttribute(HtmlTextWriterAttribute.Id, ((object) stringBuilder).ToString(), true);
                }
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
            }
            this.RenderContents(writer);
            if (!renderPanel)
                return;
            writer.RenderEndTag();
        }

        protected internal virtual void PrepareControlHierarchy()
        {
            if (this.Controls.Count == 0)
                return;
            bool controlStyleCreated = this.ControlStyleCreated;
            Table table = (Table) this.Controls[0];
            table.CopyBaseAttributes((WebControl) this);
            if (controlStyleCreated && !this.ControlStyle.IsEmpty)
            {
                table.ApplyStyle(this.ControlStyle);
            }
            else
            {
                table.GridLines = GridLines.Both;
                table.CellSpacing = 0;
            }

            TableRowCollection rows = table.Rows;
            Style s1 = (Style) this._rowStyle;
            Style s2 = (Style) new TableRowStyle();

            if (this._alternateRowStyle == null && s1 != null)
                s2.CopyFrom(s1);
            else
                s2 = this._alternateRowStyle;


            int rowCounter = 0;
            foreach (InputFormRowField gridViewRow in rows)
            {
                if (rowCounter%2 != 0)
                    gridViewRow.MergeStyle(s2);
                else
                    gridViewRow.MergeStyle(s1);

                foreach (TableCell cell in gridViewRow.Cells)
                {
                    InputFormCellField controlFieldCell = cell as InputFormCellField;
                    if (controlFieldCell != null)
                    {
                        InputFormCell containingField = controlFieldCell.ContainingField;
                        if (containingField != null)
                        {
                            if (!containingField.Visible)
                            {
                                cell.Visible = false;
                            }
                            else
                            {
                                foreach (Control control in cell.Controls)
                                {
                                    WebControl webControl = control as WebControl;
                                    Style controlStyleInternal = containingField.ControlStyleInternal;
                                    if (webControl != null && controlStyleInternal != null && !controlStyleInternal.IsEmpty)
                                        webControl.ControlStyle.CopyFrom(controlStyleInternal);
                                }
                            }
                        }
                    }
                }
                rowCounter++;
            }
        }



        private bool DetermineRenderClientScript()
        {
            return true; // this._renderClientScript;
        }

        private ArrayList _rowsArray = new ArrayList();

        protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
        {
            if (dataBinding)
            {
                DataSourceView data = this.GetData();
                if (data == null)
                {
                    throw new HttpException(CustomString.GetString("DataBoundControl_NullView", new object[1]
                                                                                                    {
                                                                                                        (object)
                                                                                                        this.ID
                                                                                                    }));
                }
                else
                {
                    ICollection collection = dataSource as ICollection;
                    if (collection == null)
                        throw new HttpException(
                            CustomString.GetString("DataBoundControl_NeedICollectionOrTotalRowCount",
                                                   new object[1]
                                                       {
                                                           (object) this.GetType().Name
                                                       }));

                }
            }

            IEnumerator enumerator1 = (IEnumerator) null;
            enumerator1 = dataSource.GetEnumerator();

            ICollection collection2 = dataSource as ICollection;

            if (collection2 == null)
                throw new HttpException(
                    CustomString.GetString("DataControls_DataSourceMustBeCollectionWhenNotDataBinding"));

            Table childTable = this.CreateChildTable();
            this.Controls.Add((Control) childTable);

            TableRowCollection rows = childTable.Rows;
            if (dataSource == null)
            {
                this.Controls.Clear();
                return 0;
            }
            else
            {

                while (enumerator1.MoveNext())
                {
                    object current = enumerator1.Current;
                    this._rowsArray.Add((object) this.CreateRow(1, 1, true, current, rows));
                }
            }


            if (AutoGenerateRows)
            {
                foreach (InputFormRow baseRow in this._rowCollection)
                {
                    this._rowsArray.Add((object) this.CreateRow(1, baseRow, rows));
                }
            }
            return 0;
        }

        private InputFormRowField CreateRow(int rowIndex, InputFormRow baseRow, TableRowCollection rows)
        {

            InputFormRowField row = new InputFormRowField(rowIndex, baseRow);
            InputFormRowEventArgs e = new InputFormRowEventArgs(row);

            //if (dataBind)
            //    row.DataItem = null;


            this.InitializeRow(row);


            //if (dataBind)
            row.DataItem = null;

            this.OnRowCreated(e);
            rows.Add((TableRow) row);
            //if (dataBind)
            {
                //row.DataBind();
                //this.OnRowDataBound(e);
                row.DataItem = (object) null;
            }
            return row;
        }

        private InputFormRowField CreateRow(int rowIndex, int dataSourceIndex, bool dataBind, object dataItem,
                                            TableRowCollection rows)
        {
            InputFormRowField row = new InputFormRowField(rowIndex, dataSourceIndex);
            InputFormRowEventArgs e = new InputFormRowEventArgs(row);

            if (dataBind)
                row.DataItem = dataItem;


            this.InitializeRow(row);


            if (dataBind)
                row.DataItem = dataItem;
            this.OnRowCreated(e);
            rows.Add((TableRow) row);
            if (dataBind)
            {
                row.DataBind();
                //this.OnRowDataBound(e);
                row.DataItem = (object) null;
            }
            return row;
        }

        protected virtual void InitializeRow(InputFormRowField row)
        {
            InputFormRowType rowType = row.RowType;

            TableCellCollection cells = row.Cells;

            object item = row.DataItem;
            if (item != null)
            {
                //Information inf = (Information) item;
            }
            else if (row.ContainingRow != null)
            {
                InputFormRow inputRow = row.ContainingRow;
                foreach (InputFormCell cell in inputRow.Cells)
                {
                    this.CreateCell(cell, cells);
                }
            }
        }

        private InputFormCellField CreateCell(InputFormCell baseCell, TableCellCollection cells)
        {
            InputFormCellField cell = new InputFormCellField(baseCell,1,1);

            InputFormCellEventArgs args = new InputFormCellEventArgs(baseCell);
            
            this.OnCellCreating(args);

            baseCell.Initialize(false, (Control)this);
            baseCell.InitializeCell(cell);
            
            this.OnCellCreated(args);

            //cell.DataBind();

            cells.Add((TableCell)cell);
            return cell;
        }
   
        private DataTable GetSource()
        {
            DataTable table = new DataTable();

            table.Columns.Add(new DataColumn("Id", typeof (string)));
            table.Columns.Add(new DataColumn("RowwNumber", typeof (string)));

            for (int counter = 0; counter < 10; counter++)
            {
                DataRow dr = table.NewRow();
                dr[0] = "Standard " + counter.ToString();
                dr[1] = counter.ToString();

                table.Rows.Add(dr);
            }

            return table;
        }

        private Table CreateChildTable()
        {
            return (Table) new InputFormTable(string.IsNullOrEmpty(this.ID) ? (string) null : this.ClientID);
        }

        protected override bool OnBubbleEvent(object source, EventArgs args)
        {

            bool handled = false;

            if (args is CommandEventArgs)
            {
                int index = 1;
                int row = 1;
                CommandEventArgs ce = (CommandEventArgs) args;
                InputFormCellCommandEventArgs cellArgs = new InputFormCellCommandEventArgs(index, row);

                OnCellCommand(cellArgs);

                handled = true;



                if (String.Compare(ce.CommandName, "Select", true) == 0)
                {
                    InputFormRowChangedEventArgs rowArgs = new InputFormRowChangedEventArgs(cellArgs.NewSelectedRowIndex);
                    OnRowChanged(rowArgs);
                }
            }
            return handled;
        }



        #endregion

        #region postback interface oriented code

        //#region private method
        //private void HandleEvent()
        //{

        //}

        //protected virtual void RaisePostBackEvent(string eventArgument)
        //{
        //    //this.ValidateEvent(this.UniqueID, eventArgument);
        //    int length = eventArgument.IndexOf('$');
        //    if (length < 0)
        //        return;
        //    this.HandleEvent();

        //}

        //private string GetCallbackScript(IButtonControl buttonControl, string argument)
        //{

        //    if (!this.DetermineRenderClientScript())
        //        return (string)null;
        //    if (string.IsNullOrEmpty(argument) && buttonControl.CommandName == "Sort")
        //        //argument = this.BuildCallbackArgument(buttonControl.CommandArgument, this.SortDirection);
        //        argument = this.BuildCallbackArgument(buttonControl.CommandArgument);//, string.Empty);
        //    if (this.Page != null)
        //        this.Page.ClientScript.RegisterForEventValidation(this.UniqueID, argument);
        //    return "javascript:__gv" + this.ClientID + ".callback" + "(" + argument + "); return false;";
        //}

        //private string BuildCallbackArgument(string p)
        //{
        //    string test = "test";
        //    return "\"" + (object)-1 + "|" + (string)(object)string.Empty + "|" +
        //           test + "|\"";
        //}


        //protected virtual void RaiseCallbackEvent(string eventArgument)
        //{
        //    string[] strArray = eventArgument.Split(new char[1]
        //                                                {
        //                                                    '|'
        //                                                });
        //    //IStateFormatter stateFormatter = this.StateFormatter;
        //    //this.ValidateEvent(this.UniqueID,
        //    //                   "\"" + strArray[0] + "|" + strArray[1] + "|" + strArray[2] + "|" + strArray[3] + "\"");
        //    //this.LoadHiddenFieldState(strArray[4], strArray[5], strArray[6], strArray[7]);
        //    //int num = int.Parse(strArray[0], (IFormatProvider)CultureInfo.InvariantCulture);
        //    //string serializedState = strArray[2];
        //    //int.Parse(strArray[1], (IFormatProvider)CultureInfo.InvariantCulture);
        //    //if (num == this.PageIndex)
        //    //{
        //    //    //SortDirection sortDirection = SortDirection.Ascending;
        //    //    //string str = (string) stateFormatter.Deserialize(serializedState);
        //    //    //if (str == this.SortExpressionInternal && this.SortDirectionInternal == SortDirection.Ascending)
        //    //    //    sortDirection = SortDirection.Descending;
        //    //    //this.SortExpressionInternal = str;
        //    //    //this.SortDirectionInternal = sortDirection;
        //    //    this._pageIndex = 0;
        //    //}
        //    //else
        //    //{
        //    //    this.EditIndex = -1;
        //    //    this._pageIndex = num;
        //    //}
        //    this.DataBind();
        //}

        //private string GetCallbackResult()
        //{
        //    return "";
        //}
        //#endregion

        #region IPostBackContainer Members

        PostBackOptions IPostBackContainer.GetPostBackOptions(IButtonControl buttonControl)
        {
            return new PostBackOptions((Control)this, "DDLCommand$DDLName");
        }

        #endregion

        //#region IPostBackEventHandler Members

        //void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
        //{
        //    this.RaisePostBackEvent(eventArgument);
        //}

        //#endregion

        //#region ICallbackContainer Members

        //string ICallbackContainer.GetCallbackScript(IButtonControl buttonControl, string argument)
        //{
        //    return this.GetCallbackScript(buttonControl, argument);

        //}

        

        //#endregion

        //#region ICallbackEventHandler Members

        //string ICallbackEventHandler.GetCallbackResult()
        //{
        //    return this.GetCallbackResult();
        //}

       

        //void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
        //{
        //    this.RaiseCallbackEvent(eventArgument);
        //}

        //#endregion


        #endregion
    }
}
